﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using CarCrash.Application.Drawing.entities;
using CarCrash.Application.Forms;

namespace CarCrash.Application.Drawing
{
 
    // панель-дисплей для рисования, содержит логику обработки
    // нажатий на мышку, клавиши и тому подобное, то есть логика
    // изменения существующий объектов
    public class Display : Panel
    {

        private int mouseDownX;
        private int mouseDownY;
        private int mouseMoveX;
        private int mouseMoveY;
        private int mouseUpX;
        private int mouseUpY;

        private bool isDragged = false;
        private bool isMouseDown = false;
        private bool isNeedToPaintSelectionBox = false;

        public void ProcessMouseClick(object sender, MouseEventArgs e)
        {
        }

        public void ProcessMouseDoubleClick(object sender, MouseEventArgs e)
        {
            controller.OpenSelectedEntityPropertyWindow(e.X, e.Y, this);
        }

        public void ProcessMouseDown(object sender, MouseEventArgs e)
        {
            isMouseDown = true;
            mouseDownX = e.X;
            mouseDownY = e.Y;
            paintedEntity = controller.ChosenEntity;
            if (paintedEntity is Line || paintedEntity is TS || paintedEntity is RoadLine)
            {
                paintedEntity.BeginX = mouseDownX;
                paintedEntity.BeginY = mouseDownY;
                paintedEntity.EndX = mouseDownX;
                paintedEntity.EndY = mouseDownY;
                controller.Add(paintedEntity);
            }
            else if (controller.OnSelectedEntityClick(mouseDownX, mouseDownY))
            { 
                // перетаскивание
                isDragged = true;
            }
        }

        public void ProcessMouseUp(object sender, MouseEventArgs e)
        {
            mouseUpX = e.X;
            mouseUpY = e.Y;
            if (paintedEntity is Line || paintedEntity is TS || paintedEntity is RoadLine)
            {
                paintedEntity.EndX = mouseUpX;
                paintedEntity.EndY = mouseUpY;
            }
            else if (isNeedToPaintSelectionBox)
            {
                controller.SetSelection(mouseDownX, mouseDownY, mouseUpX, mouseUpY);
            }
            else if (isDragged)
            {
                controller.DragSelectedEntityTo(mouseDownX, mouseDownY, mouseUpX, mouseUpY);
                this.Cursor = Cursors.Default;
                isDragged = false;
            }
            else
                controller.DropSelection(e.X, e.Y);
            paintedEntity = null;
            isMouseDown = false; isNeedToPaintSelectionBox = false;
            Invalidate();
        }
        public void ProcessMouseMove(object sender, MouseEventArgs e)
        {
            mouseMoveX = e.X;
            mouseMoveY = e.Y;
            // делаю заказ на отрисовку прямоугольника выделения
            if (!isDragged && isMouseDown && paintedEntity == null && e.Button == MouseButtons.Left)
            {
                isNeedToPaintSelectionBox = true;
                Invalidate();
            }
            else if (paintedEntity is Line || paintedEntity is RoadLine || paintedEntity is TS)
            {
                paintedEntity.EndX = mouseMoveX;
                paintedEntity.EndY = mouseMoveY;
                Invalidate();
            }
            else if (isDragged)
            {
                this.Cursor = Cursors.Hand;
            }
        }

        /*private void invalidateRectangle(int x, int y, int xx, int yy)
        {
            if (x > xx)
            {
                int buf = x; x = xx; xx = buf;
            }
            if (y > yy)
            {
                int buf = y; y = yy; yy = buf;
            }
            // чуть расширяю перерисовываемый прямоугольник, тк иногда не попадает в область
            Invalidate(new Rectangle(--x, --y, xx-x+2, yy-y+2));
        }*/

        // тут возникает вопрос, перерисовка будет всегда всей панели,
        // но часто нам надо будет перерисовавать только малую часть, надо узнать!
        protected override void OnPaint(PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            // перерисовываем все примитивы
            controller.RepaintAll(g);
            if (isNeedToPaintSelectionBox)
            {
                // прямоугольник выделения
                controller.PaintSelectionBox(g, mouseDownX, mouseDownY, mouseMoveX, mouseMoveY);
            }
        }

        // элемент, который рисуется на данный момент, например
        // если мы рисуем линию - нажали на мышь, получили начало X Y,
        // отпустили, получили конец
        private DrawableEntity paintedEntity;
        private Controller controller = Controller.Instance;

    }

}